package org.summerframework.component.security.session.service.impl;

import org.summerframework.component.security.Constants;
import org.summerframework.component.security.LoginData;
import org.summerframework.component.security.core.event.LogoutEvent;
import org.summerframework.component.security.core.service.LogoutService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;

/**
 * @author 石超
 * @version v1.0.0
 */
@Component
public class LogoutListener implements ApplicationListener<ApplicationEvent> {
    private final static Logger LOG = LoggerFactory.getLogger(LoginManageSupper.class);

    @Resource
    private LogoutService logoutService;

    @Resource
    private SessionRepository<Session> sessionRepository;

    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        if (applicationEvent instanceof SessionExpiredEvent) {
            SessionExpiredEvent event = (SessionExpiredEvent) applicationEvent;
            Session session = event.getSession();

            try {
                if (session != null) {
                    LoginData loginData = session.getAttribute(Constants.SESSION_LOGIN_DATE);
                    if (loginData != null) {
                        logoutService.logout(loginData);

                        LOG.info("清理过去的登录session成功, sessionId={} ,lastAccessedTime={}, maxInactiveIntervalInSeconds={}, 登录时长={}", session.getId(), session.getLastAccessedTime(), session.getMaxInactiveInterval().getSeconds(), Duration.between(session.getLastAccessedTime(), Instant.now()).toMinutes());

                        session.removeAttribute(Constants.SESSION_USERNAME);
                        session.removeAttribute(Constants.SESSION_USER_ID);
                        session.removeAttribute(Constants.SESSION_LOGIN_DATE);
                        session.removeAttribute(Constants.SESSION_DEVICE_TOKEN);
                    }
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        } else if (applicationEvent instanceof LogoutEvent) {
            LogoutEvent event = (LogoutEvent) applicationEvent;
            sessionRepository.deleteById(event.getLoginData().getSessionId());
        }
    }
}
